﻿using System;
using System.Drawing;
using System.Windows.Forms;
using plug_mtrximage.HelperClasses;

namespace plug_mtrximage
{
    public partial class CmixerForm : Form
    {
        public CmixerForm()
        {
        }

        public CmixerForm(bool run)
        {
            if (run)
            {
                InitializeComponent();
            }
        }

        #region Handlers
        private void RGBValueChanged(object sender, System.EventArgs e)
        {
            int r, g, b;
            if (!this.updating)
            {
                if (sender is TrackBar)
                {
                    r = redUD.Value; g = greenUD.Value; b = blueUD.Value;
                }
                else
                {
                    r = (int)rgbR.Value; g = (int)rgbG.Value; b = (int)rgbB.Value;
                }
                this.preview.BackColor = Color.FromArgb(r, g, b);
                this.updating = true;
                UpdateRGB(new RGB(r, g, b));
                UpdateHSL(ColorSpaceHelper.RGBtoHSL(r, g, b));
                UpdateHSB(ColorSpaceHelper.RGBtoHSB(r, g, b));
                UpdateCMYK(ColorSpaceHelper.RGBtoCMYK(r, g, b));
                UpdateYUV(ColorSpaceHelper.RGBtoYUV(r, g, b));
                this.updating = false;
            }
        }

        private void HSLValueChanged(object sender, System.EventArgs e)
        {
            int h, s, l;
            if (!this.updating)
            {
                if (sender is TrackBar)
                {
                    h = hueUD.Value; s = satUD.Value; l = lumUD.Value;
                }
                else
                {
                    h = (int)hslH.Value; s = (int)hslS.Value; l = (int)hslL.Value;
                }
                this.updating = true;
                UpdateHSL(new HSL(h, (double)s / 100.0, (double)l / 100.0));
                UpdateRGB(ColorSpaceHelper.HSLtoRGB((double)h, (double)s / 100.0, (double)l / 100.0));
                UpdateHSB(ColorSpaceHelper.RGBtoHSB((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                UpdateCMYK(ColorSpaceHelper.RGBtoCMYK((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                UpdateYUV(ColorSpaceHelper.RGBtoYUV((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                this.updating = false;
            }
        }

        private void HSBValueChanged(object sender, System.EventArgs e)
        {
            int h, s, b;
            if (!this.updating)
            {
                if (sender is TrackBar)
                {
                    h = hUD.Value; s = sUD.Value; b = bUD.Value;
                }
                else
                {
                    h = (int)hsbH.Value; s = (int)hsbS.Value; b = (int)hsbB.Value;
                }
                this.updating = true;
                UpdateHSB(new HSB(h, (double)s / 100.0, (double)b / 100.0));
                UpdateRGB(ColorSpaceHelper.HSBtoRGB((double)h, (double)s / 100.0, (double)b / 100.0));
                UpdateHSL(ColorSpaceHelper.RGBtoHSL((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                UpdateCMYK(ColorSpaceHelper.RGBtoCMYK((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                UpdateYUV(ColorSpaceHelper.RGBtoYUV((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                this.updating = false;
            }
        }

        private void CMYKValueChanged(object sender, System.EventArgs e)
        {
            int c, m, y, k;
            if (!this.updating)
            {
                if (sender is TrackBar)
                {
                    c = cyanUD.Value; m = magentaUD.Value; y = yellowUD.Value; k = blackUD.Value;
                }
                else
                {
                    c = (int)cmykC.Value; m = (int)cmykM.Value; y = (int)cmykY.Value; k = (int)cmykK.Value;
                }
                this.updating = true;
                UpdateCMYK(new CMYK((double)c / 100.0, (double)m / 100.0, (double)y / 100.0, (double)k / 100.0));
                UpdateRGB(ColorSpaceHelper.CMYKtoRGB((double)c / 100.0, (double)m / 100.0, (double)y / 100.0, (double)k / 100.0));
                UpdateHSL(ColorSpaceHelper.RGBtoHSL((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                UpdateHSB(ColorSpaceHelper.RGBtoHSB((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                UpdateYUV(ColorSpaceHelper.RGBtoYUV((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                this.updating = false;
            }
        }

        private void YUVValueChanged(object sender, System.EventArgs e)
        {
            int y, u, v;
            if (!this.updating)
            {
                if (sender is TrackBar)
                {
                    y = yUD.Value; u = uUD.Value; v = vUD.Value;
                }
                else
                {
                    y = (int)yuvY.Value; u = (int)yuvU.Value; v = (int)yuvV.Value;
                }
                this.updating = true;
                UpdateYUV(new YUV((double)y / 100.0, (-0.436 + ((double)u / 100.0)), (-0.615 + ((double)v / 100.0))));
                UpdateRGB(ColorSpaceHelper.YUVtoRGB((double)y / 100.0, (-0.436 + ((double)u / 100.0)), (-0.615 + ((double)v / 100.0))));
                UpdateCMYK(ColorSpaceHelper.RGBtoCMYK((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                UpdateHSL(ColorSpaceHelper.RGBtoHSL((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                UpdateHSB(ColorSpaceHelper.RGBtoHSB((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
                this.updating = false;
            }
        }

        #endregion

        #region Updates
        private void UpdateRGB(RGB rgb)
        {
            if (redUD.Value != rgb.Red || rgbR.Value != rgb.Red)
            {
                this.redUD.Value = rgb.Red;
                this.rgbR.Value = rgb.Red;
            }
            if (greenUD.Value != rgb.Green || rgbG.Value != rgb.Green)
            {
                this.greenUD.Value = rgb.Green;
                this.rgbG.Value = rgb.Green;
            }
            if (blueUD.Value != rgb.Blue || rgbB.Value != rgb.Blue)
            {
                this.blueUD.Value = rgb.Blue;
                this.rgbB.Value = rgb.Blue;
            }
            this.preview.BackColor = Color.FromArgb(rgb.Red, rgb.Green, rgb.Blue);
        }

        private void UpdateHSL(HSL hsl)
        {
            int h = Convert.ToInt32(hsl.Hue);
            int s = Convert.ToInt32(hsl.Saturation * 100);
            int l = Convert.ToInt32(hsl.Luminance * 100);
            if (h != this.hueUD.Value || h != (int)hslH.Value)
            {
                this.hueUD.Value = h;
                this.hslH.Value = h;
            }
            if (s != this.satUD.Value || s != (int)hslS.Value)
            {
                this.satUD.Value = s;
                this.hslS.Value = s;
            }
            if (l != this.lumUD.Value || l != (int)hslL.Value)
            {
                this.lumUD.Value = l;
                this.hslL.Value = l;
            }
        }

        private void UpdateHSB(HSB hsb)
        {
            int h = Convert.ToInt32(hsb.Hue);
            int s = Convert.ToInt32(hsb.Saturation * 100);
            int b = Convert.ToInt32(hsb.Brightness * 100);
            if (h != this.hUD.Value || h != (int)hsbH.Value)
            {
                this.hUD.Value = h;
                this.hsbH.Value = h;
            }
            if (s != this.sUD.Value || s != (int)hsbS.Value)
            {
                this.sUD.Value = s;
                this.hsbS.Value = s;
            }
            if (b != this.bUD.Value || b != (int)hsbB.Value)
            {
                this.bUD.Value = b;
                this.hsbB.Value = b;
            }
        }

        private void UpdateCMYK(CMYK cmyk)
        {
            int c = Convert.ToInt32(cmyk.Cyan * 100);
            int m = Convert.ToInt32(cmyk.Magenta * 100);
            int y = Convert.ToInt32(cmyk.Yellow * 100);
            int k = Convert.ToInt32(cmyk.Black * 100);
            if (c != cyanUD.Value || c != (int)cmykC.Value)
            {
                this.cyanUD.Value = c;
                this.cmykC.Value = c;
            }
            if (m != magentaUD.Value || c != (int)cmykM.Value)
            {
                this.magentaUD.Value = m;
                this.cmykM.Value = m;
            }
            if (y != yellowUD.Value || c != (int)cmykY.Value)
            {
                this.yellowUD.Value = y;
                this.cmykY.Value = y;
            }
            if (k != blackUD.Value || c != (int)cmykK.Value)
            {
                this.blackUD.Value = k;
                this.cmykK.Value = k;
            }
        }

        private void UpdateYUV(YUV yuv)
        {
            int y = Convert.ToInt32(yuv.Y * 100);
            int u = Convert.ToInt32((yuv.U + 0.436) * 100);
            int v = Convert.ToInt32((yuv.V + 0.615) * 100);

            if (y != yUD.Value || y != (int)yuvY.Value)
            {
                this.yUD.Value = y;
                this.yuvY.Value = y;
            }
            if (u != uUD.Value || u != (int)yuvU.Value)
            {
                this.uUD.Value = u;
                this.yuvU.Value = u;
            }
            if (v != vUD.Value || v != (int)yuvV.Value)
            {
                this.vUD.Value = v;
                this.yuvV.Value = v;
            }
        }

        #endregion

        private void CmixerForm_Load(object sender, EventArgs e)
        {
            this.updating = true;
            UpdateHSL(ColorSpaceHelper.RGBtoHSL((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
            UpdateHSB(ColorSpaceHelper.RGBtoHSB((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
            UpdateCMYK(ColorSpaceHelper.RGBtoCMYK((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
            UpdateYUV(ColorSpaceHelper.RGBtoYUV((int)redUD.Value, (int)greenUD.Value, (int)blueUD.Value));
            this.updating = false;
        }

    }
}
